/**
*  \file timerecorder.c
*
*  \brief
*
*  \author Michael J. Hohmann  <michael.hohmann@linde-mh.de>
*
*
*/

/*===============================================[ private includes  ]================================================*/
#include "timerecorder.h"
#include "../assertor/assertor.h"
#include "../nth/nth.h"
#include "../pal/pal_mem.h"
#include "../sdstructmgr/sdstructmgr.h"
#include "../nvram/nvram.h"

/*===============================================[ private defines   ]================================================*/

/*===============================================[ private datatypes ]================================================*/

#define TIMERECORDER_TICK_RESOLUTION 100
#define TIMERECORDER_STORE_TICKS     600  //6000
Timediag_t time_diag_interface = {0};

struct timerecoder_info
{
    U16 ticks;
    BO  last_value;
};


/** Private variables */
struct timerecorder_private
{
    struct timerecoder_times elements[timerecoder_channel_max];
    struct timerecoder_info info[timerecoder_channel_max];
    BO sleep_request;
    BO sleep_ready;
    U32 store_timer;
    BO store_data;
    struct sdstructmgr_obj my_structmgr;
};

/*===============================================[ private variables ]================================================*/
static struct timerecorder_private timerecorder;

/*===============================================[ private functions ]================================================*/

/*================================================[ inline functions ]================================================*/

/*================================================[ public functions ]================================================*/
RC timerecorder_initialize( void )
{
    pal_memzero( &timerecorder, sizeof timerecorder);

    sdstructmgr_construct( &timerecorder.my_structmgr, NVRAM_SD, &nvdata->times_management[0], &nvdata->times, sizeof(timerecorder.elements), 4 );
    if( RC_SUCCESS != sdstructmgr_get( &timerecorder.my_structmgr, &timerecorder.elements[0] ) )
    {  /* if no valid struct is found clear to default values */
        pal_memzero( &timerecorder.elements[0], sizeof timerecorder.elements );
    }

   return RC_SUCCESS;
}


void timerecoder_count( enum timerecoder_channel channel, BO value )
{
    if( timerecorder.info[channel].last_value !=value)
    {
        timerecorder.info[channel].last_value=value;
        if( value )
        {
            timerecorder.elements[channel].cycles++;
        }
    }

    if(value)
    {
        if(timerecorder.info[channel].ticks)
        {
            timerecorder.info[channel].ticks--;
        }
        else
        {
            timerecorder.info[channel].ticks=TIMERECORDER_TICK_RESOLUTION;
            timerecorder.elements[channel].time++;
        }
    }
}

U32 timerecoder_get( enum timerecoder_channel channel)
{
    return timerecorder.elements[channel].time;
}

void timerecoder_enter_sleep( void )
{
    timerecorder.sleep_ready=FALSE;
    timerecorder.sleep_request=TRUE;
}

BO timerecoder_ready_for_sleep( void )
{
    return timerecorder.sleep_ready;
}

void timerecorder_idle_service( void )
{
    if( timerecorder.store_data )
    {
        timerecorder.store_data=FALSE;
        /* write the data */
        sdstructmgr_set(  &timerecorder.my_structmgr, &timerecorder.elements[0]);
    }
}

void timerecorder_cyclic_service( void )
{
    time_diag_interface.Component_work_time = timerecorder.elements[timerecoder_channel_component_work_time].time;
    time_diag_interface.Driver_present_time = timerecorder.elements[timerecoder_channel_driver_present].time;
    time_diag_interface.Fan1_open_time = timerecorder.elements[timerecoder_channel_fan1].time;
    time_diag_interface.Fan2_open_time = timerecorder.elements[timerecoder_channel_fan2].time;
    time_diag_interface.Forward_switch_time = timerecorder.elements[timerecoder_channel_forward_switch].time;
    time_diag_interface.Neutral_switch_time = timerecorder.elements[timerecoder_channel_neutral_switch].time;
    time_diag_interface.Reverse_switch_time = timerecorder.elements[timerecoder_channel_reverse_switch].time;
    time_diag_interface.Traction_forward_time = timerecorder.elements[timerecoder_channel_traction_forward].time;
    time_diag_interface.Traction_reverse_time = timerecorder.elements[timerecoder_channel_traction_reverse].time;
    if( timerecorder.sleep_request )
    {

    }
    else
    {
        if( nth_u32( &timerecorder.store_timer, TIMERECORDER_STORE_TICKS ) )
        {
            /* store data */
            timerecorder.store_data = TRUE;
        }
    }
}
/*===============================================[ private functions ]================================================*/


/***********************************************************************************************************************
*                             Copyright 2020 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
